#include <iostream>

using namespace std;

int Study_Singleton(int argc, char** argv)
{
    int rc=0;
    
    int study_Singleton_SingleThread(int argc, char ** argv);
    rc += study_Singleton_SingleThread(argc, argv);
    
    return rc;
}

class Singleton
{
public:
    static Singleton* Instance()
    {
        if (m_instance==NULL)
        {
            m_instance = new Singleton();
            m_instance->m_value = 0;
        }
        return m_instance;
    }
    
    virtual int Get_Value() const { return m_value; }
    virtual void Set_Value(int v) { m_value = v; }
    
protected:
    int m_value;
    Singleton() { cout << ": ctor :" << endl; }
    Singleton(Singleton& copy) { cout << "Hide copy constructor" << endl; }
    //Singleton& operator= (Singleton& copy) { cout << "Hide assignment" << endl; }
    
private:
    static Singleton* m_instance;
};

Singleton* Singleton::m_instance=NULL;    

int study_Singleton_SingleThread(int argc, char ** argv)
{    
    int rc=0;
    Singleton* pSingleton1 = Singleton::Instance();
    
    cout << pSingleton1->Get_Value() << endl;
    pSingleton1->Set_Value(100);
    
    Singleton* pSingleton2 = Singleton::Instance();
    cout << pSingleton2->Get_Value() << endl;
    
    //If the copy consturctor is not protected or private, the following
    //statements will be compiled.
    /*
    Singleton anotherInstance(*pSingleton1);
    anotherInstnace.Set_Value(200);   //anotherInstance is a different instance.
    */
    
    return rc;   
}
